﻿<?php
/**
 * DESCRIPTION:
 *  class that generates a html form
 *  in this version, only forms with table-based markup are supported
 * FIELDS:
 *  public $fields is an array of form's elements
 *  protected $submit is for Submit button caption
 *  protected $td_class is a class for td
 *  protected $field_class is a class for field
 * METHODS:
 *  public void __construct($fields, $submit, $td_class="", $td_style="", $field_class="", $field_style="") is a class constructor
 *  public void print_form() generates HTML output
 *  public void __toString() overrides std function
 *  public boolean check() validates data in fields
 *  public void read_values() reads values from $_POST and sets them to form's fields (for validations etc.)
 * ======
 * @author at8eqeq3
 */
class form {
    public $fields;
    protected $name;
    protected $action;
    protected $caption;
    protected $submit;
    protected $td_class;
    protected $field_class;

    public function __construct($fields, $action, $name, $caption, $submit, $td_class = "", $td_style = "", $field_class = "", $field_style = ""){
        $this->fields = $fields;
        $this->action = $action;
        $this->caption = $caption;
        $this->name = $name;
        $this->submit = $submit;
        $this->td_class = $td_class;
        $this->td_style = $td_style;
        $this->field_class = $field_class;
        $this->field_style = $field_style;

        foreach($fields as $key => $field){
            if(!is_subclass_of($field, 'field')){
                throw new ExceptionObject($key, '<b>"'.$key.'"</b> is not a form field');
            }
        }
    }

    public function print_form(){
        $enctype = 'form/x-www-urlencoded';
        //applying classes and styles to fields, defining content-type
        if(!empty($this->fields)){
            foreach($this->fields as $field){
                if(!empty($this->field_class)){
                    $field->class = $this->field_class;
                }

                if($field->type == 'file'){
                    $enctype = 'enctype="multipart/form-data"';
                }
            }
        }

        //applying classes and styles to td's
        if(!empty($this->td_class)){
            $class = 'class="'.$this->td_class.'"';
        }else{
            $class = '';
        }
        //now it's time to put something out
        echo "<!-- form output started -->\n"; //comment this out, if no need
        echo "<form name=\"form\" action=\"backend/$this->action.php\" $enctype method=\"post\">\n";
        echo "<table>\n";
        if(!empty($this->fields)){
            foreach($this->fields as $field){
                list($caption, $tag, $help, $alternative) = $field->get_html();
                if(is_array($tag)){
                    $tag = implode("<br />", $tag);
                }
                echo "<tr>\n";
                echo "  <td width=\"100\" $class>$caption:</td>\n";
                echo "  <td $class>$tag</td>\n";
                echo "</tr>\n";
                if(!empty($help)){
                    echo "<tr>\n";
                    echo "  <td>&nbsp;</td>\n";
                    echo "  <td $class>$help</td>\n";
                    echo "</tr>\n";
                }
            }
            echo "<tr>\n";
            echo "  <td $class>&nbsp;</td>\n";
            echo "  <td $class><input class=\"button\" type=\"submit\" value=".htmlspecialchars($this->submit, ENT_QUOTES)."></td>\n";
            echo "</tr>\n";
        }
        echo "</table>\n";
        echo "</form>\n";
        echo "<!-- form output finished -->\n"; //comment this out, if no need
    }

    function print_form2(){
        $enctype = 'enctype="form/x-www-urlencoded"';
        if(!empty($this->fields)){
            foreach($this->fields as $f){
                if($f->type == 'file'){
                    $enctype = 'enctype="multipart/form-data"';
                }
                if(!empty($this->field_class)){
                    $f->class = $this->field_class;
                }
            }
        }
        
        echo "<!-- form output started -->\n";
        echo "<div class=\"form\">\n";
        echo " <form name=\"$this->name\" action=\"do.$this->action\" method=\"POST\" $enctype>\n";
        echo "  <fieldset>\n";
        echo "   <legend>$this->caption</legend>\n";

        if(!empty($_SESSION['errmsg'][$this->name])){
            echo "<div class=\"form_errmsg\">\nПроизошли следующие ошибки:\n <ul>\n";
            foreach($_SESSION['errmsg'][$this->name] as $f => $e){
                echo "  <li>$e</li>\n";
            }
            echo " </ul>\n</div>\n";
            unset($_SESSION['errmsg'][$this->name]);
        }

        if(!empty($this->fields)){
            foreach($this->fields as $f){
                echo "<p><label for=\"$f->name\" class=\"";
                if($f->is_required){
                    echo "required";
                }else{
                    echo "optional";
                }
                $tag = $f->get_html();
                //echo "\">$f->caption:</label><input type=\"$f->type\" name=\"$f->name\"></p>\n";
                echo "\">$f->caption:</label>$tag[1]</p>\n";
            }
        }
        echo "<p><input type=\"submit\" value=\"$this->submit\"></p>\n";
        echo "  </fieldset>\n";
        echo " </form>\n";
        echo "</div>\n";
        echo "<!-- form output finished -->\n";
        $serialized = serialize($this);
        $_SESSION['forms'][$this->name] = $serialized;
    }

    public function __toString(){
        $this->print_form();
    }

    public function check(){
        $arr = array();
        $ok = true;
        if(!empty($this->fields)){
            foreach($this->fields as $field){
                $str = $field->check();
                if(!empty($str)){
                    $arr[] = $str;
                    $ok = false;
                }
            }
        }
        //return $arr;
        $_SESSION['errmsg'][$this->name] = $arr;
        return $ok;
    }

    public function read_values(){
        foreach($this->fields as $n => $f){
            $f->value = $_POST[$f->name];
        }
    }
}
?>